1 Read

2 Make data frame

2.1 Exclude Protocol 8 (mother)

3 Define Functions

heat_cor_plotly <- function(df, x_vars = NULL, y_vars = NULL, low_color = "cyan",  high_color = "red",  ...){   
  # inherit type = c("pearson","spearman") from Hmisc::rcorr() 
  library(ggplot2)
  library(plotly)
  library(reshape2)
  library(Hmisc)
  
  # use all numeric columns only, print message if non-numeric are found
  numeric_cols <- unlist(lapply(df, is.numeric))
  if(!all(numeric_cols)) message("Warning: Non-numeric columns were excluded!")
  df <- df[, numeric_cols]
  
  df_mat <- as.matrix(df)
  rt <- Hmisc::rcorr(df_mat, ...)
  
  # extract correlations, p-values and merge into another dataframe
  mtlr <- reshape2::melt(rt$r, value.name = "Correlation")
  mtlp <- reshape2::melt(rt$P, value.name = "P-Value")
  
  mtl <- merge(mtlr, mtlp)
  
  # give possibility to prune the correlation matrix
  if(!is.null(x_vars)){
    mtl <- mtl[(mtl$Var1 %in% x_vars), ]
  }
  if(!is.null(x_vars)){
    mtl <- mtl[(mtl$Var2 %in% y_vars), ]
  }
  
  # want to avoid scientific notetion, but this doesnt work as numeric
  # mtl$Correlation <- as.numeric(format(mtl$Correlation, digits = 4, scientific = FALSE))  # doesnt work
  # mtl$`P-Value` <- as.numeric(format(mtl$`P-Value`, digits = 4, scientific = FALSE)) 
  options(scipen = 999)
  mtl$Correlation <- round(mtl$Correlation, 3)
  mtl$`P-Value` <- round(mtl$`P-Value`, 3)

  gx <-
    ggplot2::ggplot(mtl, 
           aes(Var1, Var2, 
               fill = Correlation,  
               text = paste("P-val = ", `P-Value`))) +
    ggplot2::geom_tile() + 
    ggplot2::scale_fill_gradient(low = low_color,  high = high_color, limits = c(-1, 1), breaks = c(-1, -.5, 0, .5, 1)) +
    ggplot2::theme_minimal() +
    {if(any(nchar(names(df)) > 6)) ggplot2::theme(axis.text.x = element_text(angle = 90, hjust = 1))}  # vertical x axis labels if lenghty
  plotly::ggplotly(gx)  
}

4 Plot Age

4.1 By Protocol

5 Analyses

5.1 Simple before-after analyses with t test

5.1.0.1 VAS Stress

NANA

null device 1

5.1.0.2 VAS Stress

NANA

null device 1

5.2 Correlations: Anotimpuri - Calitate Amintiri (without P6, P7)

5.3 Correlations: Personality - Qualities of Memories (without P6, P7)

5.4 Correlations: Social - Personality

6 Social

7 Varsta Amint - P1,P2,P3

8 Protocol 3 - Social

9 Protocol 3 - Varsta Amint



10 Session Info

R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8.1 x64 (build 9600)

Matrix products: default

locale:
[1] LC_COLLATE=Romanian_Romania.1250  LC_CTYPE=Romanian_Romania.1250    LC_MONETARY=Romanian_Romania.1250 LC_NUMERIC=C                     
[5] LC_TIME=Romanian_Romania.1250    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] RColorBrewer_1.1-2         Hmisc_4.1-1                Formula_1.2-3              survival_2.44-1.1          lattice_0.20-38           
 [6] reshape2_1.4.3             plotly_4.9.0               rio_0.5.16                 scales_1.0.0               ggpubr_0.2                
[11] magrittr_1.5               tadaatoolbox_0.16.1        summarytools_0.8.8         rstatix_0.2.0              broom_0.5.2               
[16] PerformanceAnalytics_1.5.2 xts_0.11-2                 zoo_1.8-4                  psych_1.8.12               plyr_1.8.4                
[21] forcats_0.4.0              stringr_1.4.0              dplyr_0.8.3                purrr_0.3.2                readr_1.3.1               
[26] tidyr_1.0.0                tibble_2.1.3               ggplot2_3.2.1              tidyverse_1.2.1            papaja_0.1.0.9842         
[31] pacman_0.5.1              

loaded via a namespace (and not attached):
 [1] colorspace_1.4-1    ggsignif_0.4.0      pryr_0.1.4          ellipsis_0.3.0      htmlTable_1.12      base64enc_0.1-3     rstudioapi_0.8     
 [8] DT_0.5              mvtnorm_1.0-11      lubridate_1.7.4     xml2_1.2.0          codetools_0.2-16    splines_3.6.1       mnormt_1.5-5       
[15] knitr_1.25          zeallot_0.1.0       pixiedust_0.8.6     jsonlite_1.6        cluster_2.1.0       shiny_1.2.0         compiler_3.6.1     
[22] httr_1.4.0          backports_1.1.4     assertthat_0.2.1    Matrix_1.2-17       lazyeval_0.2.2      cli_1.1.0           later_0.7.5        
[29] acepack_1.4.1       htmltools_0.3.6     tools_3.6.1         gtable_0.3.0        glue_1.3.1          Rcpp_1.0.2          carData_3.0-2      
[36] cellranger_1.1.0    vctrs_0.2.0         nlme_3.1-140        crosstalk_1.0.0     xfun_0.9            openxlsx_4.1.0      rvest_0.3.2        
[43] mime_0.7            lifecycle_0.1.0     MASS_7.3-51.4       hms_0.5.1           promises_1.0.1      parallel_3.6.1      expm_0.999-3       
[50] pwr_1.2-2           yaml_2.2.0          curl_3.2            gridExtra_2.3       pander_0.6.3        rpart_4.1-15        latticeExtra_0.6-28
[57] stringi_1.4.3       corrplot_0.84       nortest_1.0-4       checkmate_1.8.5     boot_1.3-22         zip_1.0.0           rlang_0.4.0        
[64] pkgconfig_2.0.3     matrixStats_0.54.0  bitops_1.0-6        rapportools_1.0     htmlwidgets_1.3     labeling_0.3        tidyselect_0.2.5   
[71] R6_2.4.0            DescTools_0.99.29   generics_0.0.2      pillar_1.4.2        haven_2.1.1         foreign_0.8-71      withr_2.1.2        
[78] nnet_7.3-12         abind_1.4-5         RCurl_1.95-4.11     modelr_0.1.5        crayon_1.3.4        car_3.0-2           viridis_0.5.1      
[85] grid_3.6.1          readxl_1.1.0        data.table_1.11.8   digest_0.6.21       xtable_1.8-4        httpuv_1.4.5        munsell_0.5.0      
[92] viridisLite_0.3.0   quadprog_1.5-5     
 

A work by Claudiu Papasteri

 

LS0tDQp0aXRsZTogIjxicj4gR2VuZXJhbCBQbG90cyBmb3IgTS4xLiAoQXV0b2Jpb2dyYXBoaWNhbCBNZW1vcmllcykiIA0Kc3VidGl0bGU6ICJJbml0aWFsIERhdGFzZXQiDQphdXRob3I6ICI8YnI+IENsYXVkaXUgUGFwYXN0ZXJpIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJW0gJVknKWAiDQpvdXRwdXQ6IA0KICAgIGh0bWxfbm90ZWJvb2s6DQogICAgICAgICAgICBjb2RlX2ZvbGRpbmc6IGhpZGUNCiAgICAgICAgICAgIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUNCiAgICAgICAgICAgIHRoZW1lOiBzcGFjZWxhYg0KICAgICAgICAgICAgaGlnaGxpZ2h0OiB0YW5nbw0KICAgICAgICAgICAgZm9udC1mYW1pbHk6IEFyaWFsDQogICAgICAgICAgICBmaWdfd2lkdGg6IDEwDQogICAgICAgICAgICBmaWdfaGVpZ2h0OiA5DQogICAgIyB3b3JkX2RvY3VtZW50ICAgICAgICANCiAgICAjIHBkZl9kb2N1bWVudDogDQogICAgICAgICAgICAjIHRvYzogdHJ1ZQ0KICAgICAgICAgICAgIyB0b2NfZGVwdGg6IDINCiAgICAgICAgICAgICMgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQogICAgICAgICAgICAjIGZvbnRzaXplOiAxMXB0DQogICAgICAgICAgICAjIGdlb21ldHJ5OiBtYXJnaW49MWluDQogICAgICAgICAgICAjIGZpZ193aWR0aDogNw0KICAgICAgICAgICAgIyBmaWdfaGVpZ2h0OiA2DQogICAgICAgICAgICAjIGZpZ19jYXB0aW9uOiB0cnVlDQogICAgIyBnaXRodWJfZG9jdW1lbnQ6IA0KICAgICAgICAgICAgIyB0b2M6IHRydWUNCiAgICAgICAgICAgICMgdG9jX2RlcHRoOiAyDQogICAgICAgICAgICAjIGh0bWxfcHJldmlldzogZmFsc2UNCiAgICAgICAgICAgICMgZmlnX3dpZHRoOiA1DQogICAgICAgICAgICAjIGZpZ19oZWlnaHQ6IDUNCiAgICAgICAgICAgICMgZGV2OiBqcGVnDQotLS0NCg0KDQo8IS0tIFNldHVwIC0tPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBraW50ciBvcHRpb25zDQprbml0cjo6b3B0c19jaHVuayRzZXQoDQogIGNvbW1lbnQgPSAiIyIsDQogIGNvbGxhcHNlID0gVFJVRSwNCiAgZWNobyA9IFRSVUUsIA0KICB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwgZXJyb3IgPSBGQUxTRSwNCiAgY2FjaGUgPSBUUlVFICAgICAgICMgZWNobyA9IEZhbHNlIGZvciBnaXRodWJfZG9jdW1lbnQsIGJ1dCB3aWxsIGJlIGZvbGRlZCBpbiBodG1sX25vdGVib29rDQopDQoNCiMgR2VuZXJhbCBSIG9wdGlvbnMgYW5kIGluZm8NCnNldC5zZWVkKDExMSkgICAgICAgICAgICAgICAjIGluIGNhc2Ugd2UgdXNlIHJhbmRvbWl6ZWQgcHJvY2VkdXJlcyAgICAgICANCm9wdGlvbnMoc2NpcGVuID0gOTk5KSAgICAgICAjIHBvc2l0aXZlIHZhbHVlcyBiaWFzIHRvd2FyZHMgZml4ZWQgYW5kIG5lZ2F0aXZlIHRvd2FyZHMgc2NpZW50aWZpYyBub3RhdGlvbg0KDQojIExvYWQgcGFja2FnZXMNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNrYWdlcyA8LSBjKA0KICAicGFwYWphIiwNCiAgInRpZHl2ZXJzZSIsICJwbHlyIiwgICAgICANCiAgInBzeWNoIiwgIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgICAgICAgICAgDQogICJicm9vbSIsICJyc3RhdGl4IiwNCiAgInN1bW1hcnl0b29scyIsICJ0YWRhYXRvb2xib3giLCAgICAgICAgICAgDQogICJnZ3Bsb3QyIiwgImdncHViciIsICJzY2FsZXMiLCAgICAgICAgDQogICJyaW8iDQogICMgLCAuLi4NCikNCmlmICghcmVxdWlyZSgicGFjbWFuIikpIGluc3RhbGwucGFja2FnZXMoInBhY21hbiIpDQpwYWNtYW46OnBfbG9hZChjaGFyID0gcGFja2FnZXMpDQoNCiMgVGhlbWVzIGZvciBnZ3Bsb3QyIHBsb3RpbmcgKGhlcmUgdXNlZCBBUEEgc3R5bGUpDQp0aGVtZV9zZXQodGhlbWVfYXBhKCkpDQoNCiMgVGFibGVzIGtuaXR0aW5nIHRvIFdvcmQNCmRvYy50eXBlIDwtIGtuaXRyOjpvcHRzX2tuaXQkZ2V0KCdybWFya2Rvd24ucGFuZG9jLnRvJykgICMgdGhlbiBmb3JtYXQgdGFibGVzIHVzaW5nIGFuIGlmIHN0YXRlbWVudCBsaWtlOg0KIyBpZiAoZG9jLnR5cGUgPT0gImRvY3giKSB7IHBhbmRlcjo6cGFuZGVyKGRmKSB9IGVsc2UgeyBrbml0cjo6a2FibGUoZGYpIH0NCg0KIyBTZXQgd2QgZm9yIE5vdGVib29rDQpmb2xkZXIgPC0gIkM6L1VzZXJzL01paGFpL0Rlc2t0b3AvUiBOb3RlYm9va3Mvbm90ZWJvb2tzL00uMS4gR2VuZXJhbCINCiMga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSBub3JtYWxpemVQYXRoKGZvbGRlcikpDQpgYGANCg0KDQoNCg0KDQo8IS0tIFJlcG9ydCAtLT4NCg0KDQojIFJlYWQNCg0KYGBge3IgcmVkX2NsZWFuX3JlY29kZV9tZXJnZSwgcmVzdWx0cz0naGlkZSd9DQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KIyBSZWFkDQojfn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fg0KDQojIyBSZWFkIGZpbGVzDQpmaWxlIDwtICJEYXRlIENvbXBsZXRlIE0xIHYuMTMgc2lQUEdHU1JhbWlsYXphLnNhdiINCg0KIyBzZXR3ZChmb2xkZXIpDQpEYXRhIDwtIHJpbzo6aW1wb3J0KGZpbGUucGF0aChmb2xkZXIsIGZpbGUpKQ0KYGBgDQoNCg0KIyBNYWtlIGRhdGEgZnJhbWUNCg0KYGBge3IgZGZfZXhjZWx9DQpEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KC1OdW1lKSAlPiUNCiAgICBEVDo6ZGF0YXRhYmxlKA0KICAgICAgZXh0ZW5zaW9ucyA9ICdCdXR0b25zJywNCiAgICAgIG9wdGlvbnMgPSBsaXN0KHBhZ2VMZW5ndGggPSAxMCwNCiAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFg9JzUwMHB4JywNCiAgICAgICAgICAgICAgICAgICAgIGRvbSA9ICdCZnJ0aXAnLA0KICAgICAgICAgICAgICAgICAgICAgYnV0dG9ucyA9IGMoJ2V4Y2VsJywgImNzdiIpKSkNCmBgYA0KDQoNCiMjIEV4Y2x1ZGUgUHJvdG9jb2wgOCAobW90aGVyKQ0KDQpgYGB7ciBkZl9maWx0ZXJlZH0NCkRhdGEgPC0gDQogIERhdGEgJT4lDQogIGZpbHRlcihQICE9IDgpDQpgYGANCg0KDQojIERlZmluZSBGdW5jdGlvbnMgDQoNCmBgYHtyIGRlZl9mdW5jX3R0ZXN0LCBoaWRlPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQ0KIyMgRnVuYyB0IHRlc3Qgc2kgYm94cGxvdCBzaW1wbHUNCmZ1bmNfdF9ib3ggPC0gZnVuY3Rpb24oZGYsIGluZCwgcHJlX3ZhciwgcG9zdF92YXIsIGZhY2V0ID0gRkFMU0UsIHhsYWIgPSAiIil7ICANCiAgaWYoZmFjZXQpew0KICAgIGZhY2V0IDwtICJQcm90b2NvbCINCiAgfWVsc2V7DQogICAgZmFjZXQgPC0gTlVMTA0KICB9DQogIA0KICBkZl9tb2RpZiA8LQ0KICAgIGRmICU+JQ0KICAgIHNlbGVjdChpbmQsIFAsIHByZV92YXIsIHBvc3RfdmFyKSAlPiUgDQogICAgdGlkeXI6OmRyb3BfbmEoKSAlPiUNCiAgICBnYXRoZXIocHJlX3ZhciwgcG9zdF92YXIsIGtleSA9ICJQcmVQb3N0IiwgdmFsdWUgPSAidmFsdWUiKSAlPiUgDQogICAgbXV0YXRlX2F0KHZhcnMoYygxLCAyKSksIGZ1bnMoYXMuZmFjdG9yKSkgJT4lIA0KICAgIG11dGF0ZShQcmVQb3N0ID0gZmFjdG9yKFByZVBvc3QsIGxldmVscyA9IGMocHJlX3ZhciwgcG9zdF92YXIpKSkgDQogIA0KICBpZighaXMubnVsbChmYWNldCkpew0KICAgIGRmX21vZGlmIDwtDQogICAgICBkZl9tb2RpZiAlPiUNCiAgICAgIGdyb3VwX2J5KFApICU+JQ0KICAgICAgbXV0YXRlKFByb3RvY29sID0gcGFzdGUwKCJQcm90b2NvbCA9ICIsIFAsICIsIG4gPSAiLCBuKCkpKQ0KICB9DQogIA0KICBzdGF0X2NvbXAgPC0NCiAgICBkZl9tb2RpZiAlPiUgDQogICAgZG8odGlkeSh0LnRlc3QoLiR2YWx1ZSB+IC4kUHJlUG9zdCwNCiAgICAgICAgICAgICAgICAgICBwYWlyZWQgPSBUUlVFLA0KICAgICAgICAgICAgICAgICAgIGRhdGE9LikpKQ0KICANCiAgcGxvdCA8LSANCiAgICBnZ3B1YnI6OmdncGFpcmVkKGRmX21vZGlmLCB4ID0gIlByZVBvc3QiLCB5ID0gInZhbHVlIiwgaWQgPSBpbmQsIA0KICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSAiUHJlUG9zdCIsIGxpbmUuY29sb3IgPSAiZ3JheSIsIGxpbmUuc2l6ZSA9IDAuNCwNCiAgICAgICAgICAgICAgICAgICAgIHBhbGV0dGUgPSBjKCIjMDBBRkJCIiwgIiNGQzRFMDciKSwgbGVnZW5kID0gIm5vbmUiLA0KICAgICAgICAgICAgICAgICAgICAgZmFjZXQuYnkgPSBmYWNldCwgbmNvbCA9IDMsIA0KICAgICAgICAgICAgICAgICAgICAgeGxhYiA9IHhsYWIpICsNCiAgICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCAgY29sb3VyID0gImRhcmtyZWQiKSArDQogICAgZ2dwdWJyOjpzdGF0X2NvbXBhcmVfbWVhbnMobWV0aG9kID0gInQudGVzdCIsIHBhaXJlZCA9IFRSVUUsIGxhYmVsLnggPSBhcy5udW1lcmljKGRmX21vZGlmJFByZVBvc3QpLTAuNCwgbGFiZWwueSA9IG1heChkZl9tb2RpZiR2YWx1ZSkrMSkgKyANCiAgICBnZ3B1YnI6OnN0YXRfY29tcGFyZV9tZWFucyhtZXRob2QgPSAidC50ZXN0IiwgcGFpcmVkID0gVFJVRSwgbGFiZWwgPSAicC5zaWduaWYiLCBjb21wYXJpc29ucyA9IGxpc3QoYyhwcmVfdmFyLCBwb3N0X3ZhcikpKQ0KICANCiAgcHJpbnQoc3RhdF9jb21wKQ0KICBjYXQoIlxuIikgICAgICAgICAgICAgICAgICAgICAgDQogIHByaW50KHBsb3QpDQogIGNhdCgiXG4iKQ0KICBwbG90Lm5ldygpICAgICAgICAgICAgICAgICAgICAgIyBOZWVkIHRoaXMgd29ya2Fyb3VuZCBmb3IgaW50ZXJsZWF2aW5nIHRhYmxlcyBhbmQgcGxvdHMgaW4gUiBNYXJrZG93biwgd2l0aGluIGxvb3ANCiAgZGV2Lm9mZigpDQp9DQpgYGANCg0KDQpgYGB7ciBkZWZfZnVuY19oZWF0Y29ycGxvdGx5LCBoaWRlPVRSVUUsIHJlc3VsdHM9J2FzaXMnfQ0KaGVhdF9jb3JfcGxvdGx5IDwtIGZ1bmN0aW9uKGRmLCB4X3ZhcnMgPSBOVUxMLCB5X3ZhcnMgPSBOVUxMLCBsb3dfY29sb3IgPSAiY3lhbiIsICBoaWdoX2NvbG9yID0gInJlZCIsICAuLi4peyAgIA0KICAjIGluaGVyaXQgdHlwZSA9IGMoInBlYXJzb24iLCJzcGVhcm1hbiIpIGZyb20gSG1pc2M6OnJjb3JyKCkgDQogIGxpYnJhcnkoZ2dwbG90MikNCiAgbGlicmFyeShwbG90bHkpDQogIGxpYnJhcnkocmVzaGFwZTIpDQogIGxpYnJhcnkoSG1pc2MpDQogIA0KICAjIHVzZSBhbGwgbnVtZXJpYyBjb2x1bW5zIG9ubHksIHByaW50IG1lc3NhZ2UgaWYgbm9uLW51bWVyaWMgYXJlIGZvdW5kDQogIG51bWVyaWNfY29scyA8LSB1bmxpc3QobGFwcGx5KGRmLCBpcy5udW1lcmljKSkNCiAgaWYoIWFsbChudW1lcmljX2NvbHMpKSBtZXNzYWdlKCJXYXJuaW5nOiBOb24tbnVtZXJpYyBjb2x1bW5zIHdlcmUgZXhjbHVkZWQhIikNCiAgZGYgPC0gZGZbLCBudW1lcmljX2NvbHNdDQogIA0KICBkZl9tYXQgPC0gYXMubWF0cml4KGRmKQ0KICBydCA8LSBIbWlzYzo6cmNvcnIoZGZfbWF0LCAuLi4pDQogIA0KICAjIGV4dHJhY3QgY29ycmVsYXRpb25zLCBwLXZhbHVlcyBhbmQgbWVyZ2UgaW50byBhbm90aGVyIGRhdGFmcmFtZQ0KICBtdGxyIDwtIHJlc2hhcGUyOjptZWx0KHJ0JHIsIHZhbHVlLm5hbWUgPSAiQ29ycmVsYXRpb24iKQ0KICBtdGxwIDwtIHJlc2hhcGUyOjptZWx0KHJ0JFAsIHZhbHVlLm5hbWUgPSAiUC1WYWx1ZSIpDQogIA0KICBtdGwgPC0gbWVyZ2UobXRsciwgbXRscCkNCiAgDQogICMgZ2l2ZSBwb3NzaWJpbGl0eSB0byBwcnVuZSB0aGUgY29ycmVsYXRpb24gbWF0cml4DQogIGlmKCFpcy5udWxsKHhfdmFycykpew0KICAgIG10bCA8LSBtdGxbKG10bCRWYXIxICVpbiUgeF92YXJzKSwgXQ0KICB9DQogIGlmKCFpcy5udWxsKHhfdmFycykpew0KICAgIG10bCA8LSBtdGxbKG10bCRWYXIyICVpbiUgeV92YXJzKSwgXQ0KICB9DQogIA0KICAjIHdhbnQgdG8gYXZvaWQgc2NpZW50aWZpYyBub3RldGlvbiwgYnV0IHRoaXMgZG9lc250IHdvcmsgYXMgbnVtZXJpYw0KICAjIG10bCRDb3JyZWxhdGlvbiA8LSBhcy5udW1lcmljKGZvcm1hdChtdGwkQ29ycmVsYXRpb24sIGRpZ2l0cyA9IDQsIHNjaWVudGlmaWMgPSBGQUxTRSkpICAjIGRvZXNudCB3b3JrDQogICMgbXRsJGBQLVZhbHVlYCA8LSBhcy5udW1lcmljKGZvcm1hdChtdGwkYFAtVmFsdWVgLCBkaWdpdHMgPSA0LCBzY2llbnRpZmljID0gRkFMU0UpKSANCiAgb3B0aW9ucyhzY2lwZW4gPSA5OTkpDQogIG10bCRDb3JyZWxhdGlvbiA8LSByb3VuZChtdGwkQ29ycmVsYXRpb24sIDMpDQogIG10bCRgUC1WYWx1ZWAgPC0gcm91bmQobXRsJGBQLVZhbHVlYCwgMykNCg0KICBneCA8LQ0KICAgIGdncGxvdDI6OmdncGxvdChtdGwsIA0KICAgICAgICAgICBhZXMoVmFyMSwgVmFyMiwgDQogICAgICAgICAgICAgICBmaWxsID0gQ29ycmVsYXRpb24sICANCiAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiUC12YWwgPSAiLCBgUC1WYWx1ZWApKSkgKw0KICAgIGdncGxvdDI6Omdlb21fdGlsZSgpICsgDQogICAgZ2dwbG90Mjo6c2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSBsb3dfY29sb3IsICBoaWdoID0gaGlnaF9jb2xvciwgbGltaXRzID0gYygtMSwgMSksIGJyZWFrcyA9IGMoLTEsIC0uNSwgMCwgLjUsIDEpKSArDQogICAgZ2dwbG90Mjo6dGhlbWVfbWluaW1hbCgpICsNCiAgICB7aWYoYW55KG5jaGFyKG5hbWVzKGRmKSkgPiA2KSkgZ2dwbG90Mjo6dGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSl9ICAjIHZlcnRpY2FsIHggYXhpcyBsYWJlbHMgaWYgbGVuZ2h0eQ0KICBwbG90bHk6OmdncGxvdGx5KGd4KSAgDQp9DQpgYGANCg0KDQojIFBsb3QgQWdlDQoNCmBgYHtyIHBsb3QxLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LCByZXN1bHRzPSdhc2lzJ30NCiMjIERvZGdlZCBCYXIgcGxvdCBvZiBBZ2UgYW5kIEdlbmRlcg0KRGF0YSAgJT4lDQogIG11dGF0ZShWYXJ0YV9jYXRlZyA9IGN1dChWYXJzdGEsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWtzPWMoLUluZiwgMjUsIDMwLCAzNSwgNDAsIDQ1LCA1MCwgNTUsIDYwLCBJbmYpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscz1jKCI8MjUiLCIyNS0yOSIsIjMwLTM0IiwgIjM1LTM5IiwgIjQwLTQ0IiwgIjQ1LTQ5IiwgIjUwLTU0IiwgIjU1LTU5IiwgIjYwPiIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0ID0gRkFMU0UpKSAlPiUgIA0KICBtdXRhdGUoVmFyc3RhID0gYXMuZmFjdG9yKFZhcnN0YSksDQogICAgICAgICBHZW4gPSBhcy5mYWN0b3IoYXMuY2hhcmFjdGVyKEdlbikpKSAlPiUNCiAgbXV0YXRlKEdlbiA9IGZvcmNhdHM6OmZjdF9yZWNvZGUoR2VuLCAiZmVtaW4iID0gIjEiLCAibWFzY3VsaW4iID0gIjIiKSkgJT4lDQogIGRwbHlyOjpjb3VudChWYXJ0YV9jYXRlZywgR2VuLCAuZHJvcCA9IEZBTFNFKSAlPiUgICAgICAgICAjIEdyb3VwIGJ5LCB0aGVuIGNvdW50IG51bWJlciBpbiBlYWNoIGdyb3VwIChkb250IGRyb3AgMCBjb3VudHMpDQogIG11dGF0ZShwY3QgPSBwcm9wLnRhYmxlKG4pKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAjIENhbGN1bGF0ZSBwZXJjZW50IHdpdGhpbiBlYWNoIHZhcg0KICAgIGdncGxvdChhZXMoeCA9IFZhcnRhX2NhdGVnLCB5ID0gcGN0LCBmaWxsID0gR2VuLCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwY3QpKSkgKyANCiAgICAgIGdlb21fY29sKHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UocHJlc2VydmUgPSAic2luZ2xlIiksIHN0YXQgPSAiaWRlbnRpdHkiLCkgKyAgICAjIERvbid0IGRyb3AgemVybyBjb3VudA0KICAgICAgZ2VvbV90ZXh0KHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2Uod2lkdGggPSAuOSksICAgICAgIyBtb3ZlIHRvIGNlbnRlciBvZiBiYXJzDQogICAgICAgICAgICAgICAgdmp1c3QgPSAtMC41LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIG51ZGdlIGFib3ZlIHRvcCBvZiBiYXINCiAgICAgICAgICAgICAgICBzaXplID0gMykgKyANCiAgICAgIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnQpICsNCiAgICAgIGdndGl0bGUoIiIpICsNCiAgICAgIHhsYWIoIlZhcnN0YSIpICsgeWxhYigiUGVyY2VudGFnZSAlIikgKyANCiAgICAgIGd1aWRlcyhmaWxsID0gZ3VpZGVfbGVnZW5kKHRpdGxlID0gIkdlbiIsIG5jb2wgPSAxKSkgKyANCiAgICAgIHNjYWxlX2ZpbGxfZ3JleShzdGFydCA9IDAuOCwgZW5kID0gMC4yLCBuYS52YWx1ZSA9ICJyZWQiLCBhZXN0aGV0aWNzID0gImZpbGwiKSArDQogICAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAicmlnaHQiLCBsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwgDQogICAgICAgICAgICBsZWdlbmQuanVzdGlmaWNhdGlvbiA9IGMoMCwgMSksIHBhbmVsLmJvcmRlciA9IGVsZW1lbnRfcmVjdChmaWxsID0gTkEsIGNvbG91ciA9ICJibGFjayIpKQ0KYGBgDQoNCg0KIyMgQnkgUHJvdG9jb2wNCg0KYGBge3IgcGxvdDFfMiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MjgsIHJlc3VsdHM9J2FzaXMnfQ0KIyMgRG9kZ2VkIEJhciBwbG90IG9mIEFnZSBhbmQgR2VuZGVyIGJ5IFByb3RvY29sDQpEYXRhICAlPiUNCiAgbXV0YXRlKFZhcnRhX2NhdGVnID0gY3V0KFZhcnN0YSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9YygtSW5mLCAyNSwgMzAsIDM1LCA0MCwgNDUsIDUwLCA1NSwgNjAsIEluZiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIjwyNSIsIjI1LTI5IiwiMzAtMzQiLCAiMzUtMzkiLCAiNDAtNDQiLCAiNDUtNDkiLCAiNTAtNTQiLCAiNTUtNTkiLCAiNjA+IiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlnaHQgPSBGQUxTRSkpICU+JSAgDQogIG11dGF0ZShWYXJzdGEgPSBhcy5mYWN0b3IoVmFyc3RhKSwNCiAgICAgICAgIEdlbiA9IGFzLmZhY3Rvcihhcy5jaGFyYWN0ZXIoR2VuKSkpICU+JQ0KICBtdXRhdGUoR2VuID0gZm9yY2F0czo6ZmN0X3JlY29kZShHZW4sICJmZW1pbiIgPSAiMSIsICJtYXNjdWxpbiIgPSAiMiIpKSAlPiUNCiAgZ3JvdXBfYnkoUCkgJT4lDQogIGRwbHlyOjpjb3VudChWYXJ0YV9jYXRlZywgR2VuLCAuZHJvcCA9IEZBTFNFKSAlPiUgICAgICAgICAjIEdyb3VwIGJ5LCB0aGVuIGNvdW50IG51bWJlciBpbiBlYWNoIGdyb3VwIChkb250IGRyb3AgMCBjb3VudHMpDQogIG11dGF0ZShwY3QgPSBwcm9wLnRhYmxlKG4pKSAlPiUgICAgICAgICAgICAgICAgICAgICAgICAgICAjIENhbGN1bGF0ZSBwZXJjZW50IHdpdGhpbiBlYWNoIHZhcg0KICAgIGdncGxvdChhZXMoeCA9IFZhcnRhX2NhdGVnLCB5ID0gcGN0LCBmaWxsID0gR2VuLCBsYWJlbCA9IHNjYWxlczo6cGVyY2VudChwY3QpKSkgKw0KICAgICAgZmFjZXRfd3JhcCh+UCwgc2NhbGVzID0gImZyZWUiLCBuY29sID0gMSkgKw0KICAgICAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZShwcmVzZXJ2ZSA9ICJzaW5nbGUiKSwgc3RhdCA9ICJpZGVudGl0eSIsKSArICAgICMgRG9uJ3QgZHJvcCB6ZXJvIGNvdW50DQogICAgICBnZW9tX3RleHQocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSh3aWR0aCA9IC45KSwgICAgICAjIG1vdmUgdG8gY2VudGVyIG9mIGJhcnMNCiAgICAgICAgICAgICAgICB2anVzdCA9IC0wLjUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgbnVkZ2UgYWJvdmUgdG9wIG9mIGJhcg0KICAgICAgICAgICAgICAgIHNpemUgPSAzKSArIA0KICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxhYmVscyA9IHNjYWxlczo6cGVyY2VudCkgKw0KICAgICAgZ2d0aXRsZSgiIikgKw0KICAgICAgeGxhYigiVmFyc3RhIikgKyB5bGFiKCJQZXJjZW50YWdlICUiKSArIA0KICAgICAgZ3VpZGVzKGZpbGwgPSBndWlkZV9sZWdlbmQodGl0bGUgPSAiR2VuIiwgbmNvbCA9IDEpKSArIA0KICAgICAgc2NhbGVfZmlsbF9ncmV5KHN0YXJ0ID0gMC44LCBlbmQgPSAwLjIsIG5hLnZhbHVlID0gInJlZCIsIGFlc3RoZXRpY3MgPSAiZmlsbCIpICsNCiAgICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJyaWdodCIsIGxlZ2VuZC5kaXJlY3Rpb24gPSAidmVydGljYWwiLCANCiAgICAgICAgICAgIGxlZ2VuZC5qdXN0aWZpY2F0aW9uID0gYygwLCAxKSwgcGFuZWwuYm9yZGVyID0gZWxlbWVudF9yZWN0KGZpbGwgPSBOQSwgY29sb3VyID0gImJsYWNrIikpDQpgYGANCg0KDQpgYGB7ciBwbG90MiwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NiwgcmVzdWx0cz0nYXNpcyd9DQojIyBQaWUgY2hhcnQNCkRhdGEgICU+JQ0KICBtdXRhdGUoR2VuID0gYXMuZmFjdG9yKGFzLmNoYXJhY3RlcihHZW4pKSkgJT4lDQogIG11dGF0ZShHZW4gPSBmb3JjYXRzOjpmY3RfcmVjb2RlKEdlbiwgImZlbWluIiA9ICIxIiwgIm1hc2N1bGluIiA9ICIyIikpICU+JQ0KICBncm91cF9ieShHZW4pICU+JQ0KICBkcGx5cjo6c3VtbWFyaXNlKGNvdW50cyA9IG4oKSkgJT4lDQogIG11dGF0ZShwcm9wID0gcm91bmQoY291bnRzKjEwMC9zdW0oY291bnRzKSwgMSksDQogICAgICAgICBsYWIueXBvcyA9IGN1bXN1bShwcm9wKSAtIC41KnByb3AsDQogICAgICAgICBQZXJjZW50ID0gcGFzdGUwKHByb3AsICIgJSIpKSAlPiUgDQogIGdncHVicjo6Z2dwaWUoeCA9ICJwcm9wIiwgbGFiZWwgPSAiUGVyY2VudCIsDQogICAgICAgICAgICAgICAgZmlsbCA9ICJHZW4iLCBjb2xvciA9ICJ3aGl0ZSIsIA0KICAgICAgICAgICAgICAgIGxhYi5wb3MgPSAiaW4iLCBsYWIuZm9udCA9IGxpc3QoY29sb3IgPSAid2hpdGUiKSwNCiAgICAgICAgICAgICAgICBwYWxldHRlID0gImdyZXkiKQ0KYGBgDQoNCg0KDQojIEFuYWx5c2VzDQoNCiMjIFNpbXBsZSBiZWZvcmUtYWZ0ZXIgYW5hbHlzZXMgd2l0aCB0IHRlc3QNCg0KYGBge3IgdF90ZXN0MSwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NiwgcmVzdWx0cz0nYXNpcyd9DQojIyBTaW1wbGUgYmVmb3JlLWFmdGVyIGFuYWx5c2VzIHdpdGggdCB0ZXN0DQpjYXQoIiMjIyMgVkFTIFN0cmVzcyIpDQpmdW5jX3RfYm94KERhdGEsIGluZCA9ICJJRCIsICJTdHJlc19wcmUiLCAiU3RyZXNfcG9zdCIsIGZhY2V0ID0gRkFMU0UpIA0KYGBgDQoNCg0KYGBge3IgdF90ZXN0MiwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9MTIsIHJlc3VsdHM9J2FzaXMnfQ0KIyMgU2ltcGxlIGJlZm9yZS1hZnRlciBhbmFseXNlcyB3aXRoIHQgdGVzdA0KY2F0KCIjIyMjIFZBUyBTdHJlc3MiKQ0KZnVuY190X2JveChEYXRhLCBpbmQgPSAiSUQiLCAiU3RyZXNfcHJlIiwgIlN0cmVzX3Bvc3QiLCBmYWNldCA9IFRSVUUpIA0KYGBgDQoNCg0KIyMgQ29ycmVsYXRpb25zOiBBbm90aW1wdXJpIC0gQ2FsaXRhdGUgQW1pbnRpcmkgKHdpdGhvdXQgUDYsIFA3KQ0KDQpgYGB7ciBjb3IxLCBmaWcud2lkdGg9OSwgZmlnLmhlaWdodD05LCByZXN1bHRzPSdhc2lzJ30NCmRhdGVwbG90MSA8LSBEYXRhWywgYygiUCIsICJQcmltYXZhcmEiLCAiVmFyYSIsICJUb2FtbmEiLCAiSWFybmEiLCAiTWVkaWFfczEiLCAiTWVkaWFfczIiLCAiTWVkaWFfczMiLCAgIlNvY0RpaF9QYXJ0IiwgICJTb2NEaWhfRmFtTiIsICAiU29jRGloX0ZhbUluZCIsICAiU29jRGloX1ByaWV0IiwgICJTb2NEaWhfQW1pY2kiLCAgIlNvY0RpaF9OZWN1biIsICAiU29jRGloX0FudGFnIiwgICJTb2NEaWhfVG90QXByb3AiLCAgIlNvY0RpaF9Ub3ROZWFwcm9wIiwgIlNUQUlfVCIpXSANCm5hbWVzKGRhdGVwbG90MSkgPC0gYygiUCIsICJQcmltYXZhcmEiLCAiVmFyYSIsICJUb2FtbmEiLCAiSWFybmEiLCAiUzEtIFZhbGVudGEiLCAiUzIgLSBWaXZpZG5lc3MiLCAiUzMgLSBSZWxldmFudGEiLCAgIlBhcnRlbmVyIiwgICJGYW1pbGllIG51Y2xldSIsICAiRmFtaWxpZSBleHRpbnNhIiwgICJQcmlldGVuaSIsICAiQW1pY2kiLCAgIk5lY3Vub3NjdXRpIiwgICJBbnRhZ29uaXN0aSIsICAiVG90aSBBcHJvcGlhdGlpIiwgICJUb3RpIE5lYXByb3BpYXRpaSIsICJTVEFJX1QiKQ0KZGF0ZXBsb3QxIDwtIHN1YnNldChkYXRlcGxvdDEsIFAhPTYgJiBQIT03KQ0KDQpDT1IgPC0gSG1pc2M6OnJjb3JyKGFzLm1hdHJpeChkYXRlcGxvdDFbLC0xXSkpICAgDQpNIDwtIENPUiRyDQpQX01BVCA8LSBDT1IkUA0KY29ycnBsb3Q6OmNvcnJwbG90KE0sIG1ldGhvZCA9ICJudW1iZXIiLCB0eXBlID0gInVwcGVyIiwgcC5tYXQgPSBQX01BVCwgc2lnLmxldmVsID0gMC4wNSwgaW5zaWcgPSAiYmxhbmsiLCB0bC5jb2wgPSAiYmxhY2siLCB0bC5jZXggPSAuOSwgdGwuc3J0ID0gNDUpICANCmBgYA0KDQoNCmBgYHtyIGhlYXRfY29yMSwgZmlnLndpZHRoPTksIGZpZy5oZWlnaHQ9OSwgcmVzdWx0cz0nYXNpcyd9DQpoZWF0X2Nvcl9wbG90bHkoZGF0ZXBsb3QxWywtMV0pDQpgYGANCg0KDQojIyBDb3JyZWxhdGlvbnM6IFBlcnNvbmFsaXR5IC0gUXVhbGl0aWVzIG9mIE1lbW9yaWVzICh3aXRob3V0IFA2LCBQNykNCg0KYGBge3IgY29yMiwgZmlnLndpZHRoPTExLCBmaWcuaGVpZ2h0PTExLCByZXN1bHRzPSdhc2lzJ30NCmRhdGVwbG90MiA8LSBEYXRhWywgYygyNCwgNDAsIDU2LCA4NzoxMjEsIDEyNildIA0KbmFtZXMoZGF0ZXBsb3QyKVsxOjNdIDwtIGMoIlMxLSBWYWxlbnRhIiwgIlMyIC0gVml2aWRuZXNzIiwgIlMzIC0gUmVsZXZhbnRhIikNCg0KQ09SIDwtIEhtaXNjOjpyY29ycihhcy5tYXRyaXgoZGF0ZXBsb3QyKSkgICANCk0gPC0gQ09SJHINClBfTUFUIDwtIENPUiRQDQpjb3JycGxvdDo6Y29ycnBsb3QoTSwgdHlwZSA9ICJ1cHBlciIsIHAubWF0ID0gUF9NQVQsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIiwgdGwuY29sID0gImJsYWNrIiwgdGwuY2V4ID0gLjcsIGNsLnBvcyA9ICJiIiwgdGwuc3J0ID0gNDUpDQpgYGANCg0KDQpgYGB7ciBoZWF0X2NvcjIsIGZpZy53aWR0aD00LCBmaWcuaGVpZ2h0PTEyLCByZXN1bHRzPSdhc2lzJ30NCmhlYXRfY29yX3Bsb3RseShkYXRlcGxvdDIsIHhfdmFycyA9IG5hbWVzKGRhdGVwbG90MilbMTozXSwgeV92YXJzID0gbmFtZXMoZGF0ZXBsb3QyKVstKDE6MyldKQ0KYGBgDQoNCg0KIyMgQ29ycmVsYXRpb25zOiBTb2NpYWwgLSBQZXJzb25hbGl0eQ0KDQpgYGB7ciBjb3IzLCBmaWcud2lkdGg9MTEsIGZpZy5oZWlnaHQ9MTEsIHJlc3VsdHM9J2FzaXMnfQ0KZGF0ZXBsb3QzIDwtIERhdGFbLCBjKDEzMToxMzksIDg3OjEyMSldDQpuYW1lcyhkYXRlcGxvdDMpWzE6OV0gPC0gYygiUGFydGVuZXIiLCAgIkZhbWlsaWUgbnVjbGV1IiwgICJGYW1pbGllIGV4dGluc2EiLCAgIlByaWV0ZW5pIiwgICJBbWljaSIsICAiTmVjdW5vc2N1dGkiLCAgIkFudGFnb25pc3RpIiwgICJUb3RpIEFwcm9waWF0aWkiLCAgIlRvdGkgTmVhcHJvcGlhdGlpIikNCg0KQ09SIDwtIEhtaXNjOjpyY29ycihhcy5tYXRyaXgoZGF0ZXBsb3QzKSkgICANCk0gPC0gQ09SJHINClBfTUFUIDwtIENPUiRQDQpjb3JycGxvdDo6Y29ycnBsb3QoTSwgdHlwZSA9ICJ1cHBlciIsIHAubWF0ID0gUF9NQVQsIHNpZy5sZXZlbCA9IDAuMDUsIGluc2lnID0gImJsYW5rIiwgdGwuY29sID0gImJsYWNrIiwgdGwuY2V4ID0gLjcsIGNsLnBvcyA9ICJiIiwgdGwuc3J0ID0gNDUpDQpgYGANCg0KDQpgYGB7ciBoZWF0X2NvcjMsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTEyLCByZXN1bHRzPSdhc2lzJ30NCmhlYXRfY29yX3Bsb3RseShkYXRlcGxvdDMsIHhfdmFycyA9IG5hbWVzKGRhdGVwbG90MylbMTo5XSwgeV92YXJzID0gbmFtZXMoZGF0ZXBsb3QzKVstKDE6OSldKQ0KYGBgDQoNCg0KIyBTb2NpYWwNCg0KYGBge3Igc29jXzEsIHJlc3VsdHM9J2FzaXMnLCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD05LCBmaWcuYWxpZ249J2NlbnRlcid9DQojIG5hbWVzKERhdGFbc3RyX2RldGVjdChjb2xuYW1lcyhEYXRhKSwgZml4ZWQoIlNvY0RpaCIsIGlnbm9yZV9jYXNlPVRSVUUpKV0pDQpEYXRhX3NvYyA8LQ0KICBEYXRhICU+JQ0KICBkcGx5cjo6c2VsZWN0KCJJRCIsICJQIiwgc3RhcnRzX3dpdGgoIlNvY0RpaCIpKSAlPiUNCiAgaGF2ZW46OnphcF9mb3JtYXRzKC4pICU+JSAgICAgICAgICAgICAgICAjIHRvIG5vdCBnZXQgd2FybmluZyAgDQogIGhhdmVuOjp6YXBfbGFiZWxzKC4pICU+JSAgICAgICAgICAgICAgICAgIyAiYXR0cmlidXRlcyBhcmUgbm90IGlkZW50aWNhbCBhY3Jvc3MgbWVhc3VyZSB2YXJpYWJsZXMiDQogIGhhdmVuOjp6YXBfd2lkdGhzKC4pICU+JSAgICAgICAgICAgICAgICAgIyBvbiBnYXRoZXIoKSBiZWNhdXNlIG9mIFNQU1MNCiAgZHBseXI6OnJlbmFtZV9hbGwobGlzdCh+c3RyaW5ncjo6c3RyX3JlcGxhY2UoLiwgIlNvY0RpaF8iLCAiIikpKSAlPiUgDQogIGdhdGhlcihrZXkgPSAiVmFyaWFibGUiLCB2YWx1ZSA9ICJWYWx1ZSIsIC1JRCwgLVApIA0KICANCiMgQ3JlYXRlIGEgY3VzdG9tIGNvbG9yIHNjYWxlIGZvciBhbGwgQVNDUSBncmFwaHMNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbXlDb2xvcnMgPC0gYnJld2VyLnBhbCgxMCwiU2V0MSIpDQpuYW1lcyhteUNvbG9ycykgPC0gbGV2ZWxzKERhdGFfc29jJFZhcmlhYmxlKQ0KY29sU2NhbGUgPC0gc2NhbGVfY29sb3VyX21hbnVhbChuYW1lID0gIlZhcmlhYmxlIiwgdmFsdWVzID0gbXlDb2xvcnMpDQoNCiMgUGxvdA0KZ2dwdWJyOjpnZ3Zpb2xpbihkYXRhID0gRGF0YV9zb2MsIHggPSAiVmFyaWFibGUiLCB5ID0gIlZhbHVlIiwgZmlsbCA9ICJWYXJpYWJsZSIsDQogICAgICBhZGQgPSAiYm94cGxvdCIsIGFkZC5wYXJhbXMgPSBsaXN0KGZpbGwgPSAid2hpdGUiKSwNCiAgICAgIHhsYWIgPSAiIiwgbGVnZW5kID0gIm5vbmUiKSArDQogIGNvbFNjYWxlICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIGNvbG9yIHNjYWxlIGhlcmUga2VlcCBjb25zaXN0ZW5jeSBvZiBjb2xvciB3aXRoIGZhY3RvciBsZXZlbA0KICBzdGF0X3N1bW1hcnkoZnVuLmRhdGEgPSBtZWFuX3NlLCAgY29sb3VyID0gImRhcmtyZWQiKSArICAgICAgICAgDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQpgYGB7ciBzb2NfMiwgcmVzdWx0cz0nYXNpcycsIGZpZy5oZWlnaHQ9MjgsIGZpZy53aWR0aD05LCBmaWcuYWxpZ249J2NlbnRlcid9DQojIFBsb3QgZmFjZXRlZCBieSBQcm90b2NvbA0KcCA8LSANCiAgZ2dwdWJyOjpnZ3Zpb2xpbihkYXRhID0gRGF0YV9zb2MsIHggPSAiVmFyaWFibGUiLCB5ID0gIlZhbHVlIiwgZmlsbCA9ICJWYXJpYWJsZSIsDQogICAgICAgIGFkZCA9ICJib3hwbG90IiwgYWRkLnBhcmFtcyA9IGxpc3QoZmlsbCA9ICJ3aGl0ZSIpLA0KICAgICAgICB4bGFiID0gIiIsIGxlZ2VuZCA9ICJub25lIikgKw0KICAgICAgICAgDQogICAgY29sU2NhbGUgKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgY29sb3Igc2NhbGUgaGVyZSBrZWVwIGNvbnNpc3RlbmN5IG9mIGNvbG9yIHdpdGggZmFjdG9yIGxldmVsDQogICAgc3RhdF9zdW1tYXJ5KGZ1bi5kYXRhID0gbWVhbl9zZSwgIGNvbG91ciA9ICJkYXJrcmVkIikgKyAgICAgICAgIA0KICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSkpDQoNCmdncHVicjo6ZmFjZXQocCwgZmFjZXQuYnkgPSAiUCIsIG5jb2wgPSAxLCBzY2FsZXMgPSAiZnJlZV94IikNCmBgYA0KDQoNCiMjIFNvY2lhbCAtIHRoaXMgZG9lc250IG1ha2Ugc2Vuc2UgDQoNCmBgYHtyIHNvY18zLCByZXN1bHRzPSdhc2lzJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KIyBQZXJmb3JtYW5jZUFuYWx5dGljczo6Y2hhcnQuQ29ycmVsYXRpb24oRGF0YVssIGMoOCwgMTMxLCAxMzIsIDEzMywgMTM0LCAxMzUsIDEzNiwgMTM3LCAxMzgsIDEzOSwgMTQwKV0pDQoNCiMgRXhhbXBsZSBvZiBTaW1wc29ucyBQYXJhZG94DQpjb3Bsb3QoRGlmU3RyZXMgfiBTb2NEaWhfQW1pY2kgfCBNZWRpYV9zMSwNCiAgICAgICBkYXRhID0gRGF0YSwNCiAgICAgICByb3dzID0gMSwNCiAgICAgcGFuZWwgPSBmdW5jdGlvbih4LCB5LCAuLi4pIHsNCiAgICAgICAgICBwYW5lbC5zbW9vdGgoeCwgeSwgc3BhbiA9IC44LCBpdGVyID0gNSwuLi4pDQogICAgICAgICAgYWJsaW5lKGxtKHkgfiB4KSwgY29sID0gImJsdWUiKX0pDQpgYGANCg0KDQojIFZhcnN0YSBBbWludCAtIFAxLFAyLFAzDQoNCmBgYHtyIGRpZnN0cmVzX3ZhcnN0YWFtaW50LCByZXN1bHRzPSdhc2lzJywgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KRGF0YV9QMVAyUDMgPC0gDQogIERhdGEgJT4lDQogIGZpbHRlcihQICVpbiUgYygiMSIsICIyIiwgIjMiKSkgJT4lDQogIG11dGF0ZShNZWRfYW1pbnR2YXJzdGEgPSBhcy5udW1lcmljKGFzLmNoYXJhY3RlcihNZWRfYW1pbnR2YXJzdGEpKSwNCiAgICAgICAgIERpZl9NZWRfYW1pbnR2YXJzdGEgPSBWYXJzdGEgLSBNZWRfYW1pbnR2YXJzdGEpDQoNClBlcmZvcm1hbmNlQW5hbHl0aWNzOjpjaGFydC5Db3JyZWxhdGlvbihEYXRhX1AxUDJQM1ssIGMoOCwgODUsIDEyMiwgMTQ4KV0pDQoNCmNvcGxvdChEaWZTdHJlcyB+IERpZl9NZWRfYW1pbnR2YXJzdGEgfCBNZWRpYV9zMSwNCiAgICAgICBkYXRhID0gRGF0YV9QMVAyUDMsDQogICAgICAgcm93cyA9IDEsDQogICAgIHBhbmVsID0gZnVuY3Rpb24oeCwgeSwgLi4uKSB7DQogICAgICAgICAgcGFuZWwuc21vb3RoKHgsIHksIHNwYW4gPSAuOCwgaXRlciA9IDUsLi4uKQ0KICAgICAgICAgIGFibGluZShsbSh5IH4geCksIGNvbCA9ICJibHVlIil9KQ0KYGBgDQoNCg0KIyBQcm90b2NvbCAzIC0gU29jaWFsDQoNCmBgYHtyIHAzX3NvYywgcmVzdWx0cz0nYXNpcycsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTgsIGZpZy5hbGlnbj0nY2VudGVyJ30NCkRhdGFfUDMgPC0gDQogIERhdGEgJT4lDQogIGZpbHRlcihQID09ICIzIikNCg0KUGVyZm9ybWFuY2VBbmFseXRpY3M6OmNoYXJ0LkNvcnJlbGF0aW9uKERhdGFfUDNbLCBjKDgsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCldKQ0KDQojIGNvcGxvdChTb2NEaWhfQW1pY2kgfiBEaWZTdHJlcyB8IE1lZGlhX3MxLCANCiMgICAgICAgIGRhdGEgPSBEYXRhLA0KIyAgICAgICAgY29sdW1ucyA9IDMsDQojICAgICAgcGFuZWwgPSBmdW5jdGlvbih4LCB5LCAuLi4pIHsNCiMgICAgICAgICAgIHBhbmVsLnNtb290aCh4LCB5LCBzcGFuID0gLjgsIGl0ZXIgPSA1LC4uLikNCiMgICAgICAgICAgIGFibGluZShsbSh5IH4geCksIGNvbCA9ICJibHVlIikgfSApDQpgYGANCg0KDQojIFByb3RvY29sIDMgLSBWYXJzdGEgQW1pbnQNCg0KYGBge3IgcDNfZGlmc3RyZXNfdmFyc3RhYW1pbnQsIHJlc3VsdHM9J2FzaXMnLCBmaWcuaGVpZ2h0PTgsIGZpZy53aWR0aD04LCBmaWcuYWxpZ249J2NlbnRlcid9DQpEYXRhX1AzIDwtIA0KICBEYXRhICU+JQ0KICBmaWx0ZXIoUCA9PSAiMyIpICU+JQ0KICBtdXRhdGUoTWVkX2FtaW50dmFyc3RhID0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoTWVkX2FtaW50dmFyc3RhKSksDQogICAgICAgICBEaWZfTWVkX2FtaW50dmFyc3RhID0gVmFyc3RhIC0gTWVkX2FtaW50dmFyc3RhKQ0KDQpQZXJmb3JtYW5jZUFuYWx5dGljczo6Y2hhcnQuQ29ycmVsYXRpb24oRGF0YV9QM1ssIGMoOCwgODUsIDEyMiwgMTQ4KV0pDQpgYGANCg0KDQoNCg0KDQoNCg0KDQoNCjxicj4NCg0KDQoNCg0KDQo8IS0tIFNlc3Npb24gSW5mbyBhbmQgTGljZW5zZSAtLT4NCg0KPGJyPg0KDQojIFNlc3Npb24gSW5mbw0KYGBge3Igc2Vzc2lvbl9pbmZvLCBlY2hvID0gRkFMU0UsIHJlc3VsdHMgPSAnbWFya3VwJ30NCnNlc3Npb25JbmZvKCkgICAgDQpgYGANCg0KPCEtLSBGb290ZXIgLS0+DQombmJzcDsNCjxociAvPg0KPHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlcjsiPkEgd29yayBieSA8YSBocmVmPSJodHRwczovL2dpdGh1Yi5jb20vQ2xhdWRpdVBhcGFzdGVyaS8iPkNsYXVkaXUgUGFwYXN0ZXJpPC9hPjwvcD4NCjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXI7Ij48c3BhbiBzdHlsZT0iY29sb3I6ICM4MDgwODA7Ij48ZW0+Y2xhdWRpdS5wYXBhc3RlcmlAZ21haWwuY29tPC9lbT48L3NwYW4+PC9wPg0KJm5ic3A7DQo=